package com.appspot.seqpop.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import org.slim3.datastore.Datastore;
import org.slim3.datastore.GlobalTransaction;

import com.appspot.seqpop.model.AlignedSequence;
import com.appspot.seqpop.model.Alignment;
import com.appspot.seqpop.model.Result;
import com.appspot.seqpop.model.Sequence;
import com.google.appengine.api.datastore.Key;


public class StoreService {

    public Key create(Map<String, Object> input) throws Exception {
        FastaReader reader = null;
        try {
            reader = new FastaReader((String) input.get("fasta"));
            Alignment alignment = new Alignment();
            Collection<Object> models = new ArrayList<Object>();
            models.add(alignment);

            // For counting sequences before alignment is stored.
            int count = 0;
            while (reader.hasNext()) {
                Sequence sequence = reader.getNextSequence();
                AlignedSequence aligned = alignment.add(sequence);
                count++;
                models.add(aligned);
            }
            
            if (count < 2) {
                throw new Exception("Two or more sequences are required.");
            }

            Key key = Datastore.allocateId(Alignment.class);
            alignment.setKey(key);
            
            Result result = new Result();
            alignment.getResultRef().setModel(result);
            models.add(result);

            GlobalTransaction gtx = Datastore.beginGlobalTransaction();
            gtx.put(models);
            gtx.commit();
            
            return key;
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }

    public Alignment read(Key key) {
        return Datastore.get(Alignment.class, key);
    }
    
    public void delete(Key key) {
        Collection<Key> removingKeys = new ArrayList<Key>();
        
        GlobalTransaction gtx = Datastore.beginGlobalTransaction();

        Alignment alignment = gtx.get(Alignment.class, key);
        removingKeys.add(key);
        for (Sequence sequence : alignment) {
            removingKeys.add(sequence.getKey());
        }
        
        Result result = alignment.getResultRef().getModel();
        removingKeys.add(result.getKey());
        
        gtx.delete(removingKeys);
        gtx.commit();
    }
}
